//
// CPreviewController.cpp
//

/*-----------------------------------------------------*\
			HQ Tech, Make Technology Easy!       
 More information, please go to http://hqtech.nease.net.
/*-----------------------------------------------------*/

#include "stdafx.h"
#include <streams.h>
#include "CPreviewController.h"
#include "CLiveInputFilters.h"
#include "CImageGrabberFilter.h"
#include "CLiveCapture.h"
#include "UFilterUtils.h"

// {c1f400a4-3f08-11d3-9f0b-006008039e37}
GUID CLSID_NullRenderer = {
0xc1f400a4, 0x3f08, 0x11d3, 0x9f, 0x0b, 0x00, 0x60, 0x08, 0x03, 0x9e, 0x37};


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////
CPreviewController::CPreviewController()
{
	mGrabber      = NULL; 
	mAviDecoder   = NULL;
	mNullRenderer = NULL;
}

CPreviewController::~CPreviewController()
{
	ReleaseOutputFilters();
}

BOOL CPreviewController::ConnectFilters(void)
{
	BOOL pass   = FALSE;
	IPin * pOut = NULL;
	IPin * pIn  = NULL;

	// Check to see if we should connect a image grabber
	if (mGrabber && mGrabber->GetFilter())
	{
		IPin * snapshotPin = NULL;
		if (mInputFilters->IsAGPCard())
		{
			snapshotPin = mInputFilters->GetVideoOutPin();
			pass = TryToConnectImageGrabber(snapshotPin);
			// Finally connect image grabber to Null Renderer
			pOut = mGrabber->GetPin(FALSE);
			if (!mNullRenderer)
			{
				mNullRenderer = new CDXFilter(mGraph->GetGraph(),
					CLSID_NullRenderer, "Null Renderer");
				mNullRenderer->CreateFilter();
			}
			pIn  = mNullRenderer->GetPin(TRUE);
			pass = mGraph->ConnectFilters(pOut, pIn);
			// Get AGP Preview pin for later connecting...
			pOut = mInputFilters->GetPreviewPin();
		}
		else
		{
			snapshotPin = mInputFilters->GetPreviewPin();
			pass = TryToConnectImageGrabber(snapshotPin);
			// Get the output pin of image grabber for later connecting...
			pOut = mGrabber->GetPin(FALSE);
		}	
	}
	else
	{
		pOut = mInputFilters->GetPreviewPin();
	}

	// Finally connect video preview pin to the video renderer
	pIn = mVideoRenderer->GetInputPin();
	if (pOut && pIn)
	{
		pass = mGraph->ConnectFilters(pOut, pIn);
	}

	// Connect audio stream to the audio renderer
	pOut = mInputFilters->GetAudioOutPin();
	pIn  = mAudioRenderer->GetPin(TRUE);
	if (pass && pOut && pIn)
	{
		pass = mGraph->ConnectFilters(pOut, pIn);
	}

	return pass;
}

BOOL CPreviewController::TryToConnectImageGrabber(IPin * inOutputPin)
{
	IPin * pOut = inOutputPin;
	IPin * pIn  = mGrabber->GetPin(TRUE);

	// Try snapshot pin to image grabber directly
	BOOL pass = mGraph->ConnectFilters(pOut, pIn);
	if (!pass)
	{
		// Try snapshot pin to avi decompressor
		if (!mAviDecoder)
		{
			mAviDecoder = new CDXFilter(mGraph->GetGraph(),
				CLSID_AVIDec, "AVI Decompressor");
			mAviDecoder->CreateFilter();
		}
		pIn = mAviDecoder->GetPin(TRUE);
		pass = mGraph->ConnectFilters(pOut, pIn);

		// Try avi decompressor to image grabber
		pOut = mAviDecoder->GetPin(FALSE);
		pIn  = mGrabber->GetPin(TRUE);
		pass = mGraph->ConnectFilters(pOut, pIn);
	}

	return pass;
}

BOOL CPreviewController::CreateOutputFilters(void)
{
	BOOL pass = CGraphController::CreateOutputFilters();
	if (pass)
	{
		// If grabbing flag is valid, create our grabber filter
		if (mLiveCapture->IsGrabEnabled())
		{
			mGrabber = new CImageGrabberFilter(mGraph->GetGraph());
			pass = mGrabber->CreateFilter();
			mGrabber->SetFieldPicture(mInputFilters->IsFieldPicture());
		}
	}
	return pass;
}

void CPreviewController::ReleaseOutputFilters(void)
{
	SAFE_DELETE(mGrabber);
	SAFE_DELETE(mAviDecoder);
	SAFE_DELETE(mNullRenderer);

	CGraphController::ReleaseOutputFilters();
}

BOOL CPreviewController::SnapshotToFile(const char * inFile)
{
	if (mIsGraphActive) 	
	{
		if (mGrabber && mGrabber->GetFilter() &&
			UFilterUtils::IsCompletelyConnected(mGrabber->GetFilter()))
		{
			return mGrabber->SnapshotToFile(inFile);
		}
		else if (mLiveCapture->IsVMRPreferred())
		{
			return mGraph->GetCurrentImage(inFile);
		}		
	}
	return FALSE;
}

